package com.idealighter.game.games.fruitslot.manager;

import com.google.inject.Inject;
import com.google.inject.Singleton;

import com.idealighter.game.core.constant.room.RoomActiveConstant;
import com.idealighter.game.dictionary.dic.FruitslotRoomTypeDic;
import com.idealighter.game.dictionary.domain.FruitslotRoomDomain;
import com.idealighter.game.gamehall.dto.MemInfo;
import com.idealighter.game.games.common.AbstractTable;
import com.idealighter.game.games.common.RoomState;
import com.idealighter.game.games.fruitslot.common.FruitslotReward;
import com.idealighter.game.games.fruitslot.dto.BasketDto;
import com.idealighter.game.games.fruitslot.dto.RoomInfo;
import com.idealighter.game.games.fruitslot.dto.RoomTypeDetailInfo;
import com.idealighter.game.games.fruitslot.dto.SelfSeatInfoDto;
import com.idealighter.game.games.fruitslot.message.ResChipsChangeMsg;
import com.idealighter.game.games.fruitslot.message.ResEnterGameHallMsg;
import com.idealighter.game.games.fruitslot.message.ResEnterRoomMsg;
import com.idealighter.game.games.fruitslot.message.ResEnterTableMsg;
import com.idealighter.game.games.fruitslot.message.ResFastEnterTableMsg;
import com.idealighter.game.games.fruitslot.message.ResFruitslotStartMsg;
import com.idealighter.game.games.fruitslot.message.ResGameInfoMsg;
import com.idealighter.game.games.fruitslot.struct.FruistlotBasket;
import com.idealighter.game.games.fruitslot.struct.FruitslotRoom;
import com.idealighter.game.games.fruitslot.struct.FruitslotSeat;
import com.idealighter.game.games.shuihu.message.ResDiceGameStartMsg;
import com.idealighter.game.games.shuihu.message.ResExchangeChipsMsg;
import com.idealighter.game.games.shuihu.message.ResXiaoMaLiStartMsg;
import com.idealighter.game.message.core.ResMessage;
import com.idealighter.game.player.manager.PlayerMsgWriter;
import com.idealighter.game.player.struct.Player;
import com.idealighter.utils.check.EmptyUtil;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * 水浒传消息管理 .
 * 
 * @date 2015年9月28日 下午2:13:48
 *
 */
@Singleton
public class FruitslotMsgMgr {

  @Inject
  private PlayerMsgWriter msgWriter;
  @Inject
  private FruitslotDataMgr dataMgr;
  @Inject
  private FruitslotRoomTypeDic roomTypeDic;

  private RoomInfo getRoomInfo(FruitslotRoom room) {
    FruitslotRoomDomain roomDomain = room.getRoomDomain();

    RoomInfo roomInfo = null;
    if (roomDomain.getIsActive() == RoomActiveConstant.ACTIVE) {
      roomInfo = new RoomInfo();
      roomInfo.setRoomId(room.getId().intValue());
      roomInfo.setName(roomDomain.getName());
      roomInfo.setType(roomDomain.getType());
      roomInfo.setMaxNum(roomDomain.getMaxNum());
      roomInfo.setFree(roomDomain.getFree());
      roomInfo.setGeneral(roomDomain.getGeneral());
      roomInfo.setCrowded(roomDomain.getCrowded());
      roomInfo.setLower(roomDomain.getLower());
      roomInfo.setUpper(roomDomain.getUpper());
      roomInfo.setProportionGold(roomDomain.getProportionGold());
      roomInfo.setProportionChips(roomDomain.getProportionChips());
      roomInfo.setTable(roomDomain.getTableNum());
      roomInfo.setAfee(roomDomain.getAfee());
      roomInfo.setInType(roomDomain.getInType());
      roomInfo.setPlayerNum(room.getPlayers().size());
      roomInfo.setStatus(roomStatus(room).desc);
      roomInfo.setDisplayNames(roomDomain.getDisplays());
      roomInfo.setPlaceHolder(roomDomain.getPlaceHolder());
      roomInfo.setRobotLower(roomDomain.getRobotLower());
      roomInfo.setRobotUpper(roomDomain.getRobotUpper());
      roomInfo.setBets(roomDomain.getBets());
    }
    return roomInfo;
  }

  /**
   * 发送进入大厅消息.
   */
  public ResMessage resEnterGameHallMsg() {
    ResEnterGameHallMsg msg = new ResEnterGameHallMsg();

    Collection<FruitslotRoom> rooms = dataMgr.newestRooms();
    for (FruitslotRoom room : rooms) {


      RoomInfo roomInfo = getRoomInfo(room);
      if (roomInfo == null) {
        continue;
      }

      FruitslotRoomDomain roomDomain = room.getRoomDomain();
      RoomTypeDetailInfo roomTypeDetailInfo = new RoomTypeDetailInfo();

      roomTypeDetailInfo.setType(roomDomain.getType());
      roomTypeDetailInfo.setTypeName(roomTypeDic.map().get(roomDomain.getType()).getName());

      roomTypeDetailInfo.getRooms().add(roomInfo);

      msg.getRoomTypes().add(roomTypeDetailInfo);
    }

    return msg;
  }

  /**
   * 房间状态，空闲,普通,拥挤,爆满.
   * 
   * @param room 水浒房间.
   * @return 房间状态.
   */
  private RoomState roomStatus(FruitslotRoom room) {
    int playersNum = room.getPlayers().size();
    FruitslotRoomDomain roomDom = room.getRoomDomain();

    if (playersNum < roomDom.getMaxNum() * roomDom.getFree() / 100) {
      return RoomState.IDLE;
    } else if (playersNum < roomDom.getMaxNum() * roomDom.getGeneral() / 100) {
      return RoomState.GENERAL;
    } else if (playersNum < roomDom.getMaxNum() * roomDom.getCrowded() / 100) {
      return RoomState.CROWD;
    } else {
      return RoomState.FULL;
    }
  }

  /**
   * 发送进入桌子消息.
   * 
   * @param player 玩家.
   */
  public ResMessage resEnterRoomMsg(Player player) {
    ResEnterRoomMsg msg = new ResEnterRoomMsg();
    for (AbstractTable table : player.curRoom.tables()) {
      msg.getTables().add(table.tableInfo());
    }
    msg.setMembers(player.curRoom.memInfos());

    return msg;
  }

  /**
   * 发送进入桌子消息.
   */
  public ResMessage resEnterTableMsg(List<MemInfo> mems) {
    ResEnterTableMsg msg = new ResEnterTableMsg();
    msg.setMems(mems);
    return msg;
  }

  /**
   * 发送兑换筹码消息.
   * 
   * @param seat 座位.
   */
  public void sendChipsChangeMsg(FruitslotSeat seat) {
    ResChipsChangeMsg msg = new ResChipsChangeMsg();
    msg.setChips(seat.getTotalChips());
    msg.setPlayerId(seat.getPlayerId());
    msgWriter.writeMsg(seat.getPlayerId(), msg);
  }

  /**
   * 发送兑换筹码结果消息(前端要求).
   * 
   * @param seat 座位.
   */
  public void sendExchangeChipsMsg(FruitslotSeat seat) {
    ResExchangeChipsMsg msg = new ResExchangeChipsMsg();
    msg.setChips(seat.getTotalChips());
    msgWriter.writeMsg(seat.getPlayerId(), msg);
  }

  /**
   * 向同桌的玩家发送进入牌桌消息.
   * 
   * @param player 玩家.
   * @param seat 座位.
   * @param res 0:成功;1:该位置有人 .
   */
  /*
   * public . void sendEnterTableMsg(Player player, FruitslotSeat seat, int res) { ResEnterTableMsg
   * msg . = new ResEnterTableMsg(); msg.getSeats().add(seat.seatInfo()); msg.setRes(res);
   * 
   * msgWriter.writeMsg(player, . msg); }
   */

  /**
   * 发送座位信息更新.
   * 
   * @param seat 座位.
   */
  /*
   * public . void sendSeatInfoUpdateMsg(FruitslotSeat seat) { ResSeatInfoUpdateMsg msg = new
   * ResSeatInfoUpdateMsg(); msg.setSeat(seat.seatInfo()); sendRoomPlayersMsg(seat.table.room, msg);
   * } .
   */

  /**
   * 发送快速进入结果消息.
   */
  public ResFastEnterTableMsg resFastEnterTableMsg(List<MemInfo> mems, long totalChips) {
    ResFastEnterTableMsg msg = new ResFastEnterTableMsg();
    msg.setMems(mems);
    msg.setTotalChips(totalChips);
    return msg;
  }

  /**
   * 发送水浒传开始消息.
   * 
   * @param seat 座位.
   * @param shuiHuReward 奖励.
   */
  public ResFruitslotStartMsg resFruitslotStartMsg(FruitslotSeat seat,
      FruitslotReward shuiHuReward) {
    ResFruitslotStartMsg msg = new ResFruitslotStartMsg();
    // msg.setRes(res);

    msg.setBonus(seat.getBonus());
    for (Map<Integer, Integer> row : seat.getIcons().rowMap().values()) {
      msg.getIcons().addAll(row.values());
    }
    msg.setType(shuiHuReward.getType());
    msg.getLineRewards().addAll(shuiHuReward.getLineRewardIconsList());
    msg.setTotalWin(shuiHuReward.getWin());

    List<BasketDto> basketDtos = new ArrayList<>();
    if (EmptyUtil.listIsNotEmpty(seat.getLotteryRewards())) {
      for (Iterator<FruistlotBasket> iterator = seat.getLotteryRewards().iterator(); iterator
          .hasNext();) {
        FruistlotBasket basket = iterator.next();
        BasketDto dto = new BasketDto();
        dto.setMultiple(basket.getMultiple());
        dto.setRate(basket.getRate());
        basketDtos.add(dto);
      }
    }
    msg.setLotteryRewards(basketDtos);

    return msg;
  }

  /**
   * 发送骰子游戏开始结果消息.
   * 
   * @param seat 座位.
   * @param res 0:开始成功,1:双比筹码不足
   * @param point1 .
   * @param point2 .
   * @param win 0:输,非0:本局赢得的筹码 .
   */
  public void sendDiceGameStartMsg(FruitslotSeat seat, int res, int point1, int point2, long win) {
    ResDiceGameStartMsg msg = new ResDiceGameStartMsg();
    msg.setRes(res);
    msg.setPoint1(point1);
    msg.setPoint2(point2);
    msg.setWin(win);
    msg.setTotalWin(seat.getBillChips());
    msgWriter.writeMsg(seat.getPlayerId(), msg);
  }

  /**
   * 发送小玛丽开始结果消息.
   * 
   * @param seat 座位.
   * @param insideIcons 里面icon.
   * @param outsideIcon 外面icon.
   * @param win 小玛丽当局赢得筹码 .
   */
  public void sendXiaoMaLiStartMsg(FruitslotSeat seat, List<Integer> insideIcons, int outsideIcon,
      long win) {
    ResXiaoMaLiStartMsg msg = new ResXiaoMaLiStartMsg();
    msg.setInsideIcons(insideIcons);
    msg.setOutsideIcon(outsideIcon);
    msg.setWin(win);
    msg.setTotalWin(seat.getBillChips());
    msg.setOver(seat.getBonus() == 0 ? 1 : 0);
    msgWriter.writeMsg(seat.getPlayerId(), msg);
  }



  /**
   * 向同房间的玩家(包括自己)发送消息.
   * 
   * @param room 房间.
   * @param msg 消息.
   */
  public void sendRoomPlayersMsg(FruitslotRoom room, ResMessage msg) {
    room.getPlayers().forEach(p -> msgWriter.writeMsg(p, msg));
  }

  /**
   * 返回游戏信息.
   * 
   * @param player 玩家.
   * @return 游戏信息.
   */
  public ResMessage resGameInfo(Player player) {
    ResGameInfoMsg msg = new ResGameInfoMsg();
    if (player.curRoom instanceof FruitslotRoom && player.curSeat != null) {

      FruitslotSeat curSeat = (FruitslotSeat) player.curSeat;
      SelfSeatInfoDto selfInfo = new SelfSeatInfoDto();

      selfInfo.setBet(curSeat.getBet());
      selfInfo.setBillChips(curSeat.getBillChips());
      curSeat.setTotalChips(player.getGold());
      selfInfo.setTotalChips(curSeat.getTotalChips());
      selfInfo.setBonus(curSeat.getBonus());
      selfInfo.setGaming(curSeat.isGaming());
      List<Integer> icons = null;
      if (!curSeat.getIcons().isEmpty() && !curSeat.getIcons().rowMap().isEmpty()) {
        icons = new ArrayList<>();
        for (Map<Integer, Integer> row : curSeat.getIcons().rowMap().values()) {
          icons.addAll(row.values());
        }
      }
      selfInfo.setIcons(icons);
      selfInfo.setLine(curSeat.getLine());

      List<BasketDto> basketDtos = new ArrayList<>();
      if (EmptyUtil.listIsNotEmpty(curSeat.getLotteryRewards())) {
        for (Iterator<FruistlotBasket> iterator = curSeat.getLotteryRewards().iterator(); iterator
            .hasNext();) {
          FruistlotBasket basket = iterator.next();
          BasketDto dto = new BasketDto();
          dto.setMultiple(basket.getMultiple());
          dto.setRate(basket.getRate());
          basketDtos.add(dto);
        }
      }
      selfInfo.setLotteryRewards(basketDtos);
      msg.setInfo(selfInfo);
      RoomInfo roomInfo = getRoomInfo((FruitslotRoom) player.curRoom);
      msg.setRoomInfo(roomInfo);
    } else {
      player.curRoom = null;
      player.curTable = null;
      player.curSeat = null;
    }
    return msg;
  }
}
